package com.zjpavt.client.page;

import com.zjpavt.client.command.todaycommand.TodayCommandManager;
import com.zjpavt.client.event.EventRegisterCenter;
import com.zjpavt.client.hal.LedScreen;
import com.zjpavt.client.hal.LoopManager;
import com.zjpavt.client.page.pageunit.ScreenLine;
import com.zjpavt.client.page.abstractpage.AbstractEditablePage;
import com.zjpavt.client.page.editableunit.EditUnitNum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;

import static java.lang.Integer.parseInt;

/**
 *第九页 当天定时器页面
 * @author gxy
 */
public class TimerPage extends AbstractEditablePage {
    private static final Logger log = LoggerFactory.getLogger(TimerPage.class);
    private List<EditUnitNum> blinkUnitList;
    private static final int INDEX_PAGE_UNIT_START_HOUR = 0;
    private static final int INDEX_PAGE_UNIT_START_MINUTE = 1;
    private static final int INDEX_PAGE_UNIT_START_SECOND = 2;
    private static final int INDEX_PAGE_UNIT_END_HOUR = 3;
    private static final int INDEX_PAGE_UNIT_END_MINUTE = 4;
    private static final int INDEX_PAGE_UNIT_END_SECOND = 5;
    private EventRegisterCenter eventRegisterCenter = EventRegisterCenter.getInstance();
    private int loopNum = 0;


    public TimerPage(int pageNum, long mRefreshPeriod) {
        super(pageNum, mRefreshPeriod);
        TodayCommandManager.TodayCommandBean copyTodayCommand = TodayCommandManager.getInstance().getCopyTodayCommand();
        copyTodayCommand.initData();
//		回路修改后初始化定时器页面的回路状态与任务
        eventRegisterCenter.addLoopChangeTask(()-> {
            if(loopNum != LoopManager.getInstance().getLoopNum() && !isInEditMode()) {
                initEditUnits();
                initDefaultVal();
            }
        });
    }

    @Override
    public void initEditUnits() {
        loopNum = LoopManager.getInstance().getLoopNum();
        int defaultLoopNum = LoopManager.DEFAULT_LOOP_NUMBER;
        clearEditUnit();
        addEditUnit(new EditUnitNum(2, 1, 2, 0, 23, 1));
        addEditUnit(new EditUnitNum(2, 4, 5, 0, 59, 1));
        addEditUnit(new EditUnitNum(2, 7, 8, 0, 59, 1));
        addEditUnit(new EditUnitNum(3, 1, 2, 0, 23, 1));
        addEditUnit(new EditUnitNum(3, 4, 5, 0, 59, 1));
        addEditUnit(new EditUnitNum(3, 7, 8, 0, 59, 1));
        blinkUnitList = new ArrayList<>();
        if (loopNum <= defaultLoopNum) {
            for (int i = 1; i <= loopNum; i++) {
                blinkUnitList.add(new EditUnitNum(4, i, i, 0, 1, 1));
            }
            maxInnerPageNum = 1;
        } else {
//			根据回路组的数量初始化最大页面数量 根据回路数量决定可编辑块的数量。
            if (PageManager.getInstance().getLoopGroupControlPage() != null) {
                List<LoopGroupControlPage.LoopGroup> loopGroupList = PageManager.getInstance().getLoopGroupControlPage().getLoopGroups();
                for (LoopGroupControlPage.LoopGroup loopGroup: loopGroupList) {
                    for (int i = 1; i <= loopGroup.getSwitchSize(); i++) {
                        blinkUnitList.add(new EditUnitNum(4, i, i, 0, 1, 1));
                    }
                }
                maxInnerPageNum = loopGroupList.size() + 1;
            }
        }
        blinkUnitList.forEach(this::addEditUnit);
    }

    @Override
    public void refreshPage() {
        loopNum = LoopManager.getInstance().getLoopNum();
//如果是在浏览模式下 最后一行显示最长的15位数据
        if (!isInEditMode()) {
            if (loopNum < LedScreen.SCREEN_WIDTH) {
                TodayCommandManager.TodayCommandBean copyTodayCommand = TodayCommandManager.getInstance().getCopyTodayCommand();
                String commandShowPage = copyTodayCommand.getTodayTimerCommand();
                LedScreen.getInstance().setText(getContent(copyTodayCommand.getStartTime(), copyTodayCommand.getCloseTime(), commandShowPage));
            } else {
                List<LoopGroupControlPage.LoopGroup> loopGroupList = PageManager.getInstance().getLoopGroupControlPage().getLoopGroups();
                if (indexOfInnerPage == 0) {
                    TodayCommandManager.TodayCommandBean copyTodayCommand = TodayCommandManager.getInstance().getCopyTodayCommand();
                    String commandShowPage = copyTodayCommand.getTodayTimerCommand();
                    LedScreen.getInstance().setText(getContent(copyTodayCommand.getStartTime(), copyTodayCommand.getCloseTime(), commandShowPage));
                } else {
                    LedScreen.getInstance().setText(getContentWithoutEdit(loopGroupList.get(indexOfInnerPage -1)));
                }
            }
        } else {
//			编辑时间或者回路长度单页面能够显示 使用包含编辑时间的页面  否则使用回路组的显示方式
            if (isEditTime() || loopNum <LedScreen.SCREEN_WIDTH) {
//				编辑模式下 所有信息使用缓存的可编辑对象
                StringBuilder commandBuilder = new StringBuilder();
                for (int index = 0; index < Math.min(LedScreen.SCREEN_WIDTH, loopNum); index++) {
                    commandBuilder.append(getCommandEditUnitText(index));
                }
                String startTime = getEditUnit(0).getText() + ":" + getEditUnit(1).getText() + ":" + getEditUnit(2).getText();
                String closeTime = getEditUnit(3).getText() + ":" + getEditUnit(4).getText() + ":" + getEditUnit(5).getText();
                LedScreen.getInstance().setText(getContent(startTime, closeTime, commandBuilder.toString()));
            } else {
                TodayCommandManager.TodayCommandBean copyTodayCommand = TodayCommandManager.getInstance().getCopyTodayCommand();
//			currentBlinkIndex从0开始
                int currentBlinkCommandIndex = getCurrentBlinkIndexOfCommand();
                List<LoopGroupControlPage.LoopGroup> loopGroupList = PageManager.getInstance().getLoopGroupControlPage().getLoopGroups();
                for (LoopGroupControlPage.LoopGroup loopGroup: loopGroupList) {
                    if (currentBlinkCommandIndex < loopGroup.getSwitchSize()) {
                        LedScreen.getInstance().setText(getContent(loopGroup));
//						不加break的时候，会把后续的页面覆盖掉前面的页面
                        break;
                    } else {
                        currentBlinkCommandIndex -= loopGroup.getSwitchSize();
                    }
                }
            }
        }
    }

    /***
     * 获取当前闪烁的位置在Command中的位置
     * begin at 0
     * @return
     */
    private int getCurrentBlinkIndexOfCommand() {
        return getCurrBlinkIndex() - 6;
    }

    /**
     * 开始时间 结束时间占据6个可编辑单元 表示还在编辑时间
     * @return
     */
    private boolean isEditTime() {
        return getCurrBlinkIndex() < 6;
    }

    /**
     * 获取在可编辑单元中的指令 从0开始
     * @param indexBeginAt0
     * @return
     */
    private String getCommandEditUnitText(int indexBeginAt0) {
        return getEditUnit(indexBeginAt0 + 6).getText();
    }

    /**
     * 不带有定时器时间的页面
     * 根据回路分组修改定时器状态
     * @param loopGroup 回路分组状态
     * @return
     */
    private List<ScreenLine> getContent(LoopGroupControlPage.LoopGroup loopGroup) {
        List<ScreenLine> lists = new ArrayList<>();
        StringBuilder stringBuilder = new StringBuilder();
//		从1开始  需要转会为0
        for (int index = loopGroup.getFirstIndexInLoopManager() -1; index < loopGroup.getFirstIndexInLoopManager() + loopGroup.getSwitchSize() -1; index++) {
            stringBuilder.append(getCommandEditUnitText(index));
        }
        String status = stringBuilder.toString();
        lists.add(new ScreenLine.ScreenLineBuilder().text("Timer set:").pageNum(getPageNum()).build());
        lists.add(new ScreenLine.ScreenLineBuilder().text(loopGroup.getGroupName()).build());
        lists.add(new ScreenLine.ScreenLineBuilder()
                  .text(loopGroup.getFirstIndexInSlave() + "-"
                        + (loopGroup.getFirstIndexInSlave() + loopGroup.getSwitchSize()-1)
                        +"      Ext"+ loopGroup.getExtendNum()
                       ).build()
                 );
        lists.add(new ScreenLine.ScreenLineBuilder().text(status).build());
        return lists;
    }

    /**
     * 不带有定时器时间的页面
     * 根据回路分组修改定时器状态
     * 没有被编辑的状态
     * @param loopGroup 回路分组状态
     * @return
     */
    private List<ScreenLine> getContentWithoutEdit(LoopGroupControlPage.LoopGroup loopGroup) {
        List<ScreenLine> lists = new ArrayList<>();
        String todayCommand = TodayCommandManager.getInstance().getCopyTodayCommand().getTodayTimerCommand();
        String status = todayCommand.substring(loopGroup.getFirstIndexInLoopManager() - 1, loopGroup.getSwitchSize() + loopGroup.getFirstIndexInLoopManager() - 1);
        lists.add(new ScreenLine.ScreenLineBuilder().text("Timer set:").pageNum(getPageNum()).build());
        lists.add(new ScreenLine.ScreenLineBuilder().text(loopGroup.getGroupName()).build());
        lists.add(new ScreenLine.ScreenLineBuilder()
                  .text(loopGroup.getFirstIndexInSlave() + "-"
                        + (loopGroup.getFirstIndexInSlave() + loopGroup.getSwitchSize()-1)
                        +"      Ext"+ loopGroup.getExtendNum()
                       ).build()
                 );
        lists.add(new ScreenLine.ScreenLineBuilder().text(status).build());
        return lists;
    }

    /**
     * 带有离线指令显示时间的页面
     * @param startTime
     * @param endTime
     * @param command	大于屏幕的话会在ScreenLine中剪除
     * @return
     */
    private List<ScreenLine> getContent(String startTime, String endTime, String command) {
        List<ScreenLine> lists = new ArrayList<>();
        lists.add(new ScreenLine.ScreenLineBuilder().text("Timer set:").pageNum(getPageNum()).build());
        lists.add(new ScreenLine.ScreenLineBuilder().text(startTime).build());
        lists.add(new ScreenLine.ScreenLineBuilder().text(endTime).build());
        lists.add(new ScreenLine.ScreenLineBuilder().text(command).build());
        return lists;
    }

    /**
     * 根据当前状态设置unit初始值
     */
    @Override
    public void setDefaultVal() {
        TodayCommandManager.TodayCommandBean copyTodayCommand = TodayCommandManager.getInstance().getCopyTodayCommand();
        String commandArray = copyTodayCommand.getTodayTimerCommand();
        getEditUnit(INDEX_PAGE_UNIT_START_HOUR).setCurrentVal(copyTodayCommand.getLocalStartTime().getHour());
        getEditUnit(INDEX_PAGE_UNIT_START_MINUTE).setCurrentVal(copyTodayCommand.getLocalStartTime().getMinute());
        getEditUnit(INDEX_PAGE_UNIT_START_SECOND).setCurrentVal(copyTodayCommand.getLocalStartTime().getSecond());
        getEditUnit(INDEX_PAGE_UNIT_END_HOUR).setCurrentVal(copyTodayCommand.getLocalCloseTime().getHour());
        getEditUnit(INDEX_PAGE_UNIT_END_MINUTE).setCurrentVal(copyTodayCommand.getLocalCloseTime().getMinute());
        getEditUnit(INDEX_PAGE_UNIT_END_SECOND).setCurrentVal(copyTodayCommand.getLocalCloseTime().getSecond());
        for (int i = 0; i < Math.min(commandArray.length(),blinkUnitList.size()); i++) {
            blinkUnitList.get(i).setCurrentVal(commandArray.charAt(i)-'0');
        }
    }

    /**
     * 根据当前状态设置unit初始值
     */
    protected void initDefaultVal() {
        TodayCommandManager.TodayCommandBean copyTodayCommand = TodayCommandManager.getInstance().getCopyTodayCommand();
        String commandArray = copyTodayCommand.getTodayTimerCommand();
        getEditUnit(INDEX_PAGE_UNIT_START_HOUR).setCurrentValWithoutBlink(copyTodayCommand.getLocalStartTime().getHour());
        getEditUnit(INDEX_PAGE_UNIT_START_MINUTE).setCurrentValWithoutBlink(copyTodayCommand.getLocalStartTime().getMinute());
        getEditUnit(INDEX_PAGE_UNIT_START_SECOND).setCurrentValWithoutBlink(copyTodayCommand.getLocalStartTime().getSecond());
        getEditUnit(INDEX_PAGE_UNIT_END_HOUR).setCurrentValWithoutBlink(copyTodayCommand.getLocalCloseTime().getHour());
        getEditUnit(INDEX_PAGE_UNIT_END_MINUTE).setCurrentValWithoutBlink(copyTodayCommand.getLocalCloseTime().getMinute());
        getEditUnit(INDEX_PAGE_UNIT_END_SECOND).setCurrentValWithoutBlink(copyTodayCommand.getLocalCloseTime().getSecond());
        for (int i = 0; i < Math.min(commandArray.length(),blinkUnitList.size()); i++) {
            blinkUnitList.get(i).setCurrentValWithoutBlink(commandArray.charAt(i)-'0');
        }
    }


    @Override
    public void saveVal() {
        LocalTime startLocalTime = LocalTime.of(parseInt(getEditUnit(INDEX_PAGE_UNIT_START_HOUR).getText()),
                                                parseInt(getEditUnit(INDEX_PAGE_UNIT_START_MINUTE).getText()),
                                                parseInt(getEditUnit(INDEX_PAGE_UNIT_START_SECOND).getText()));
        LocalTime endLocalTime = LocalTime.of(parseInt(getEditUnit(INDEX_PAGE_UNIT_END_HOUR).getText()),
                                              parseInt(getEditUnit(INDEX_PAGE_UNIT_END_MINUTE).getText()),
                                              parseInt(getEditUnit(INDEX_PAGE_UNIT_END_SECOND).getText()));
        StringBuilder command = new StringBuilder();
        blinkUnitList.forEach(value -> command.append(value.getText()));
        TodayCommandManager.getInstance().setTodayTimerCommand(startLocalTime, endLocalTime, command.toString());
        refreshPage();
    }

    private int indexOfInnerPage = 0;
    public int maxInnerPageNum;
    @Override
    public void onKeySet() {
        super.onKeySet();
        refreshPage();
    }

    @Override
    public void onKeyEnt() {
        if (isInEditMode()) {
            super.onKeyEnt();
        } else {
            indexOfInnerPage++;
            indexOfInnerPage = indexOfInnerPage % maxInnerPageNum;
            refreshPage();
        }
    }

    @Override
    public void onKeyDown() {
        this.indexOfInnerPage = 0;
        super.onKeyDown();
    }

    @Override
    public void onKeyUp() {
        this.indexOfInnerPage = 0;
        super.onKeyUp();
    }
}
